﻿using System.Collections;
using System.Collections.Generic;
using System.Web.Mvc;
using KaytechSoftware.Cms.App.Areas.Admin.Interfaces;
using KaytechSoftware.Cms.App.Areas.Admin.Models;
using KaytechSoftware.Cms.App.Areas.Admin.Models.Base;
using KaytechSoftware.Cms.Services.Interfaces;
using System.Linq;
using KaytechSoftware.Cms.Services.Interfaces.Entity;

namespace KaytechSoftware.Cms.App.Areas.Admin.Controllers
{
    public abstract class GridController<TFilterModel, TEntityModel, TEntityDto> : Controller where TFilterModel : GridFiltersModel, new() where TEntityModel : GridEntityModel, IGridEntityModel<TEntityDto>, new() where TEntityDto : IDto
    {
        protected IOrderedEntityService<TEntityDto> EntityService;

        protected GridController(IOrderedEntityService<TEntityDto> entityService)
        {
            EntityService = entityService;
        }

        protected string ControllerName
        {
            get { return GetType().Name.Replace("Controller", string.Empty); }
        }

        protected TEntityModel CreateEntityModel()
        {
            var model = new TEntityModel();
            model.ControllerName = ControllerName;
            return model;
        }

        public abstract ActionResult Add();

        public abstract ActionResult Edit(long id);

        public abstract void OnPreSave(TEntityModel editModel);

        public virtual ActionResult Save(TEntityModel editModel)
        {
            OnPreSave(editModel);
            EntityService.Save(editModel.ToDto());
            return RedirectToAction("List", editModel.ControllerName);
        }

        public ActionResult Details(TEntityModel entityModel)
        {
            return View("Details", entityModel);
        }

        public abstract TFilterModel RestoreOrGetDefaultFilters();

        public abstract void RegisterCollectionsForFilters(TFilterModel filters);

        protected abstract IList<TEntityDto> Filter(TFilterModel filtersModel);

        [HttpGet]
        public ActionResult List()
        {
            var filters = RestoreOrGetDefaultFilters();
            return List(filters);
        }

        [HttpPost]
        public ActionResult List(TFilterModel filterModel)
        {
            var items = Filter(filterModel);
            RegisterCollectionsForFilters(filterModel);
            var entityModel = items.Select(i => new TEntityModel().FromDto(i)).ToList();
            var model = new GridModel(entityModel, filterModel);
            model.ControllerName = ControllerName;

            return View(model);
        }

        public virtual ActionResult Delete(long id)
        {
            EntityService.Delete(id);
            return RedirectToAction("List");
        }

        public virtual ActionResult Up(long id)
        {
            EntityService.MoveUp(id);
            return RedirectToAction("List");
        }

        public virtual ActionResult Down(long id)
        {
            EntityService.MoveDown(id);
            return RedirectToAction("List");
        }
    }
}